package com.ys.web.ws.send.controller;

import com.ys.base.BaseConstants;
import com.ys.base.EnumType;
import com.ys.utils.base.http.McodeHandler;
import com.ys.utils.base.http.ResponseHandler;
import com.ys.utils.base.j2se.DateHandler;
import com.ys.utils.base.j2se.JsonUtil;
import com.ys.utils.base.j2se.StringHandler;
import com.ys.utils.help.GroupUtils;
import com.ys.utils.redis.Redis;
import com.ys.utils.redis.key.UserKey;
import com.ys.utils.spring.properties.Config;
import com.ys.web.ws.bean.MessageNoticeBean;
import com.ys.web.ws.bean.MessageNoticeEntity;
import com.ys.web.ws.bean.MessageRequestBean;
import com.ys.web.ws.bean.MessageResponseBean;
import com.ys.web.ws.send.service.MessageService;
import com.ys.web.ws.send.vo.QueryHistoryVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * @author quxinjun
 * @version 1.0.0
 * @ClassName MessageController.java
 * @Description 控制器
 * @createTime 2021年05月06日 17:13:00
 */
@Slf4j
@RestController
@RequestMapping("/message")
public class MessageController {

    @Autowired
    private MessageService messageService;


   /**
    * @ 名称:发送用户消息
    * @ 创建人: dhf
    * @ 参数： null
    * @ 创建时间: 2022/5/11
    * @ 修改人和其它信息
    * @ 返回值:
    */
    @PostMapping("/sendMessageUser")
    public String sendMessageUser(@RequestAttribute String uid, MessageRequestBean messageRequestBean) {
        if(StringHandler.isNotEmpty(messageRequestBean.data)){
            String keyWord = Config.pp.get("msg.data.key.word.list");
            messageRequestBean.data = StringHandler.keywordReplace(keyWord,messageRequestBean.data);
        }
        //参数验证
        String errMsg = messageRequestBean.validateParam(messageRequestBean, BaseConstants.MessageConstants.MESSAGE_USER);
        if (!StringHandler.isEmpty(errMsg)) {
            return ResponseHandler.error(EnumType.ResponseCode.ILLEGAL.getCode(), errMsg);
        }
        messageService.sendMessageUser(messageRequestBean,StringHandler.getLong(uid));
        return ResponseHandler.success();
    }

    /**
     * @ 名称:发送组别消息
     * @ 创建人: dhf
     * @ 参数： null
     * @ 创建时间: 2022/5/11
     * @ 修改人和其它信息
     * @ 返回值:
     */
    @PostMapping("/sendMessageGroup")
    public String sendMessageGroup(@RequestAttribute String uid, MessageRequestBean messageRequestBean) {
        if(StringHandler.isNotEmpty(messageRequestBean.data)){
            String keyWord = Config.pp.get("msg.data.key.word.list");
            messageRequestBean.data = StringHandler.keywordReplace(keyWord,messageRequestBean.data);
        }
        //参数验证
        String errMsg = messageRequestBean.validateParam(messageRequestBean, BaseConstants.MessageConstants.MESSAGE_GROUP);
        if (!StringHandler.isEmpty(errMsg)) {
            return ResponseHandler.error(EnumType.ResponseCode.ILLEGAL.getCode(), errMsg);
        }
        messageService.sendMessageGroup(messageRequestBean);
        return ResponseHandler.success();
    }

    /**
     * @ 名称:发送系统消息
     * @ 创建人: dhf
     * @ 参数： null
     * @ 创建时间: 2022/5/11
     * @ 修改人和其它信息
     * @ 返回值:
     */
    @PostMapping("/sendMessageSystem")
    public String sendMessageSystem(MessageRequestBean messageRequestBean) {
        //参数验证
        String errMsg = messageRequestBean.validateParam(messageRequestBean, BaseConstants.MessageConstants.MESSAGE_SYSTEM);
        if (!StringHandler.isEmpty(errMsg)) {
            return ResponseHandler.error(EnumType.ResponseCode.ILLEGAL.getCode(), errMsg);
        }
        messageService.sendMessageSystem(messageRequestBean);
        return ResponseHandler.success();
    }

    /**
     * @ 名称:用户点击面板修改未读消息为已读
     * @ 创建人: dhf
     * @ 参数： null
     * @ 创建时间: 2022/5/11
     * @ 修改人和其它信息
     * @ 返回值:
     */
    @PostMapping("/clickToReadMessage")
    public String clickToReadMessage(@RequestAttribute Long uid) {
        messageService.clickToReadMessage(uid);
        return ResponseHandler.success();
    }

    public List<MessageResponseBean> getUserApplyList(Long uid) {
        List<MessageResponseBean> userApplyList = messageService.getUserApplyList(uid);
        return userApplyList;
    }

   /**
    * @ 名称:获取用户未读消息
    * @ 创建人: dhf
    * @ 参数： null
    * @ 创建时间: 2022/5/11
    * @ 修改人和其它信息
    * @ 返回值:
    */
    public List<MessageResponseBean> getUnReadMessage(Long uid) {
//        Redis.key.del(UserKey.unReadMessageKey(McodeHandler.to32Radix(uid)));
        List<MessageResponseBean> list = new ArrayList<>();
        String unReadMessageKey = UserKey.unReadKey(uid);
        if (Redis.key.exists(unReadMessageKey)) {
            Map map = Redis.hash.hgetall(unReadMessageKey);
            List<String> arrayList = new ArrayList<String>(map.values());
            arrayList.forEach(x -> {
                list.add(JsonUtil.jsonToBean(x, MessageResponseBean.class));
            });
        }

        String userUnReadMessageEntityKey = UserKey.userUnReadMessageEntityKey(uid);
        if (Redis.key.exists(userUnReadMessageEntityKey)) {
            Map hgetall = Redis.hash.hgetall(userUnReadMessageEntityKey);
            if (!hgetall.isEmpty()) {
                List<String> groupChatList = new ArrayList<String>(hgetall.values());
                groupChatList.forEach(x -> list.add(JsonUtil.jsonToBean(x, MessageResponseBean.class)));
            }
        }

        List<MessageResponseBean> noticeList = messageService.getUserNoticeList(uid);
        if (noticeList != null && !noticeList.isEmpty()) {
            list.addAll(noticeList);
        }

        List<MessageResponseBean> clearList = messageService.getClearList(uid);
        if (clearList != null && !clearList.isEmpty()) {
            list.addAll(clearList);
        }

        if (!list.isEmpty()) {
            Map<String, String> map = new HashMap<>();
            list.stream().filter(x -> StringHandler.isNotEmpty(x.getMessageId())).forEach(x -> map.put(x.getMessageId(), JsonUtil.toJson(x)));
            Redis.hash.hmset(unReadMessageKey, map);
            Redis.key.setKeyTimeout(unReadMessageKey, 300L);
        }

        Map<Object, Boolean> seen = new ConcurrentHashMap<>();
        return list.stream().filter(x -> StringHandler.isNotEmpty(x.getMessageId())).filter(x -> distinctByKey(x.getMessageId() + "_" + x.getCode(), seen)).collect(Collectors.toList());
    }

    //去重同样的 messageId 聊天记录
    public static boolean distinctByKey(String messageId, Map<Object, Boolean> seen) {
        return seen.putIfAbsent(messageId, Boolean.TRUE) == null;
    }


    @GetMapping("/testPush")
    public void testPush(Long uid) {
        //禁用人数少于20的群  并且对应用户不能创建群聊
//        messageService.freezeGroupAndUserCreate();


//        messageService.query();

        messageService.groupMessage();
    }

    /**
     * @ 名称:消息唯一标识符
     * @ 创建人: dhf
     * @ 参数： null
     * @ 创建时间: 2022/5/11
     * @ 修改人和其它信息
     * @ 返回值:
     */
    @PostMapping("/undoMessage")
    public String undoMessage(@RequestAttribute String uid, MessageRequestBean messageRequestBean) {
        if (StringHandler.isEmpty(messageRequestBean)) {
            return ResponseHandler.error(EnumType.ResponseCode.Fail.getCode(), "参数传递出错");
        }
        messageService.undoMessage(uid, messageRequestBean);
        return ResponseHandler.success();
    }

    /**
     * @ 名称:群聊历史记录
     * @ 创建人: dhf
     * @ 参数： null
     * @ 创建时间: 2022/5/11
     * @ 修改人和其它信息
     * @ 返回值:
     */
    @PostMapping("/queryHistoryChatGroup")
    public String queryHistoryChatGroup(@RequestAttribute Long uid, QueryHistoryVo queryHistoryVo) {
        queryHistoryVo.checkParam();
        List<MessageResponseBean> list = messageService.queryHistoryChatGroup(uid, queryHistoryVo);
        return ResponseHandler.list(list);
    }


    /**
     * @ 名称:私聊历史记录
     * @ 创建人: dhf
     * @ 参数： null
     * @ 创建时间: 2022/5/11
     * @ 修改人和其它信息
     * @ 返回值:
     */
    @PostMapping("/queryHistorySingleChat")
    public String queryHistorySingleChat(@RequestAttribute Long uid, QueryHistoryVo queryHistoryVo) {
        queryHistoryVo.checkParam();
        queryHistoryVo.setQueryId(StringHandler.getString(McodeHandler.from32Radix(queryHistoryVo.getQueryId())));
        List<MessageResponseBean> list = messageService.queryHistorySingleChat(uid, queryHistoryVo);
        return ResponseHandler.list(list);
    }

    @PostMapping("/sendNotice")
    public String sendNotice(@RequestBody MessageNoticeBean messageNoticeBean) {
        MessageNoticeEntity messageNoticeEntity = GroupUtils.parsData(messageNoticeBean);
        if (!messageNoticeEntity.getMembers().isEmpty()) {
            messageNoticeEntity.getMembers().forEach(x -> GroupUtils.sendIfAbsent(messageNoticeEntity.getMessage(), x, messageNoticeEntity.getMessage().getWindowId()));
        }
        return ResponseHandler.success();
    }

    @RequestMapping("/del")
    public void del(){

        String key = UserKey.userUnReadMessageEntityKey(58241);

        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern(BaseConstants.BASE_FORMAT);
        LocalDateTime compareTime;
        compareTime = now.plusHours(-now.getHour());
        System.err.println(compareTime);
        Map<Object, Object> map = Redis.hash.hgetall(key);
        Map<String, String> newMap = new HashMap<>();
        LocalDateTime finalCompareTime = compareTime;
        List<String> befor = new ArrayList<>();
        List<String> after = new ArrayList<>();
        map.forEach((k, v) -> {
            MessageResponseBean messageResponseBean = JsonUtil.jsonToBean((String) v, MessageResponseBean.class);
            if (StringHandler.isNotEmpty(messageResponseBean.getGroupId())) {
                if (StringHandler.isNotEmpty(messageResponseBean.getCreateTime())) {
                    try {
                        LocalDateTime time = LocalDateTime.parse(messageResponseBean.getCreateTime(), dtf);
                        if (finalCompareTime.isBefore(time)) {
                            after.add(time.format(dtf));
                            newMap.put(messageResponseBean.getMessageId(), v.toString());
                        }

                        befor.add(time.format(dtf));
                    } catch (Exception e) {
                        log.error("MessageGroupClearSchedule---删除群未读消息错误",v,e);
                        newMap.put(messageResponseBean.getMessageId(), v.toString());
                    }
                }
            } else {
                newMap.put(messageResponseBean.getMessageId(), v.toString());
            }
        });
        System.err.println(map.size());
        System.err.println(newMap.size());

        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.HOUR_OF_DAY,-1);
        long DayTime = StringHandler.getLong(sdf.format(calendar.getTime()));
        System.err.println(DayTime);
        Map<Object, Object> map1 = Redis.hash.hgetall(key);
        Map<String, String> newMap1 = new HashMap<>();
        long finalCompareTime1 = DayTime;
        map.forEach((k, v) -> {
            MessageResponseBean messageResponseBean = JsonUtil.jsonToBean((String) v, MessageResponseBean.class);
            if (StringHandler.isNotEmpty(messageResponseBean.getGroupId())) {
                if (StringHandler.isNotEmpty(messageResponseBean.getCreateTime())) {
                    try {
                        long time = DateHandler.getLongFormatDate(messageResponseBean.getCreateTime());
                        if (finalCompareTime1<time) {
                            newMap1.put(messageResponseBean.getMessageId(), v.toString());
                        }
                    } catch (Exception e) {
                        log.error("MessageGroupClearSchedule---删除群未读消息错误",v,e);
                        newMap1.put(messageResponseBean.getMessageId(), v.toString());
                    }
                }
            } else {
                newMap1.put(messageResponseBean.getMessageId(), v.toString());
            }
        });
        System.err.println(newMap1.size());
    }
}
